package com.dgut.edu.cn.design.mode.filterchain;

import com.dgut.edu.cn.design.mode.filterchain.filter.RuleFilter;
import com.dgut.edu.cn.design.mode.filterchain.handler.PriceCompareHandle;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * @description: 需要解析配置，然后拿到每个业务的过滤点模式
 * @author: hongbin.zheng
 * @create: 2023-08-11 10:26
 **/
@Service
@Slf4j
public class FilterChainFactory<T> {
	@Autowired
	private ApplicationContext applicationContext;
	private Map<String, RuleFilter> ruleFilterMap;
	private Map<String, PriceCompareHandle> priceCompareHandleMap;

	@PostConstruct
	public void init() throws NoSuchMethodException {
		ruleFilterMap = Maps.newHashMap();
		priceCompareHandleMap = Maps.newHashMap();
		Map<String, RuleFilter> filterBeanMap = applicationContext.getBeansOfType(RuleFilter.class);
		for (Map.Entry<String, RuleFilter> entry : filterBeanMap.entrySet()) {
			ruleFilterMap.put(entry.getKey(), entry.getValue());
		}

		Map<String, PriceCompareHandle> handleBeanMap = applicationContext.getBeansOfType(PriceCompareHandle.class);
		for (Map.Entry<String, PriceCompareHandle> entry : handleBeanMap.entrySet()) {
			priceCompareHandleMap.put(entry.getKey(), entry.getValue());
		}
	}

	public <T> FilterChain<T> createChains(FilterChainConfig config, Class<T> tClass) {
		FilterChain<T> filterChain = new FilterChain<T>(config.getName());
		if (CollectionUtils.isNotEmpty(config.getFilterList())) {
			for (String ruleFilterName : config.getFilterList()) {
				RuleFilter<T> ruleFilter = ruleFilterMap.get(ruleFilterName);
				if (ruleFilter != null) {
					filterChain.getRuleFilterList().add(ruleFilter);
				}
			}
		}


		if (CollectionUtils.isNotEmpty(config.getHandlerList())) {
			for (String handle : config.getHandlerList()) {
				PriceCompareHandle<T> priceCompareHandle = priceCompareHandleMap.get(handle);
				if (priceCompareHandle != null) {
					filterChain.getPriceCompareHandleList().add(priceCompareHandle);
				}
			}
		}


		return filterChain;
	}
}
